package com.wxx.socket;

import com.wxx.socket.server.HttpRequestHandler;
import com.wxx.socket.server.SocketChannelHandler;
import com.wxx.socket.util.LogUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.internal.SystemPropertyUtil;

import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

/**
 * @author wxx
 * 描述：开启服务
 */
public class StartServer {
    private static final EventLoopGroup bossGroup = new NioEventLoopGroup(
            Math.max(1,
                    SystemPropertyUtil.getInt("io.netty.eventLoopThreads",
                    Runtime.getRuntime().availableProcessors() * 2)
            )
    );
    private static final EventLoopGroup workerGroup = new NioEventLoopGroup(4);

    public static void main(String[] args) {
        startSocketServer();
        startHttpServer();
    }



    /**
     * 开启Socket服务器
     */
    private static void startSocketServer() {
        int port = 9876;
        ServerBootstrap socketServer = new ServerBootstrap();
        socketServer.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ch.pipeline()
                                .addLast(new StringDecoder(Charset.forName("GBK")))
                                .addLast(new StringEncoder(Charset.forName("GBK")))
                                .addLast(new IdleStateHandler(0,0,6 * 60, TimeUnit.SECONDS))
                                .addLast(new SocketChannelHandler());
                    }
                });
        socketServer.bind(Config.IP, port).addListener((ChannelFutureListener) channelFuture -> {
            if (channelFuture.isSuccess()) {
                LogUtil.log("Socket服务启动>>>ip=" + Config.IP + "  port=" + port);
            } else {
                LogUtil.log("Socket服务器启动失败>>>" + channelFuture.cause().getMessage());
            }
        });
    }

    /**
     * 开启HTTP服务器
     */
    private static void startHttpServer() {
        int port = 9003;
        String DEFAULT_HTTP_URL = "/im";
        ServerBootstrap httpServer = new ServerBootstrap();
        httpServer.group(new NioEventLoopGroup(), new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new HttpRequestDecoder())
                                .addLast(new HttpObjectAggregator(65536))
                                .addLast(new HttpResponseEncoder())
                                .addLast(new ChunkedWriteHandler())
                                .addLast(new HttpRequestHandler(DEFAULT_HTTP_URL));
                    }
                });
        httpServer.bind(Config.IP, port).addListener((ChannelFutureListener) channelFuture -> {
            if (channelFuture.isSuccess()) {
                LogUtil.log("Http服务启动>>>http://" + Config.IP + ":" + port + DEFAULT_HTTP_URL);
            } else {
                LogUtil.log("Http服务启动失败>>>" + channelFuture.cause().getMessage());
            }
        });
    }
}
